package com.rdxer.api;

import com.rdxer.api.para.AccountSignupPara;
import com.rdxer.api.para.LoginPara;
import com.rdxer.dataview.AuthTokenDV;
import com.rdxer.model.Account;
import com.rdxer.core.security.JWTConfiguration;
import com.rdxer.service.AccountService;
import com.rdxer.core.entity.Result;
import com.rdxer.core.ex.ToStringEx;
import com.rdxer.core.exception.exceptions.BaseException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.query.Param;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.security.Principal;
import java.util.Date;
import java.util.Map;

// 接口
@CrossOrigin
@RestController
public class AuthApi {
    @Resource
    AccountService accountService;
    @Autowired
    private JWTConfiguration jwtConfiguration;


    @PostMapping("/login")
    public Result<AuthTokenDV> login(@RequestBody LoginPara loginPara){

        AuthTokenDV token = accountService.login(loginPara);

        return Result.ofSucceed(token);
    }

    @PostMapping("/logout")
    public Result<String> logout(@RequestHeader Map<String,String> header,@AuthenticationPrincipal Principal principal){
        ToStringEx.toStringWithPrettyPrint(header);
        return Result.ofSucceed("登出成功");
    }

    // 注册
    @PostMapping("/signup")
    public Result<Account> signup(@RequestBody AccountSignupPara account){
        Account a = new Account();

        BeanUtils.copyProperties(account,a);

        Account register = accountService.register(a);

        return Result.ofSucceed(register);
    }

    /**
     * 签发获取用户信息权限的token
     * @param principal
     * @return
     */
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_SUPER_ADMIN')")
    @GetMapping("/getClientSignToken")
    public Result<String> getClientSignToken(@AuthenticationPrincipal Principal principal){

        String token = Jwts.builder()
                .setSubject(principal.getName())
                .setAudience("client:getUserInfo")
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS512, jwtConfiguration.secret)
                .compact();

        return Result.ofSucceed("ok",token);
    }

    /**
     * 获取用户信息
     * @return
     */
    @GetMapping("/client/account/{username}")
    public Result<Account> getAccount(@Param("token") String token, @PathVariable String username){

        if (StringUtils.isEmpty(token)) {
            throw BaseException.ofForbidden();
        }

        var jwt = Jwts.parser()
                .setSigningKey(jwtConfiguration.secret)
                .parseClaimsJws(token.replace(jwtConfiguration.jwt_prefix, "").trim());
        Claims body = jwt.getBody();

        String audience = body.getAudience();
        if (!"client:getUserInfo".equals(audience)) {
            throw BaseException.ofForbidden("拒绝访问2");
        }
        Account show = accountService.findByName(username);
        return Result.ofSucceed("ok",show);
    }
}

